package ija.net;

import ija.controller.CheckersController;
import ija.controller.CheckersController.Confirm;
import ija.model.basis.Desk;
import ija.model.basis.Figure;
import ija.xls.notation.NotationReaderFactory;

import java.awt.event.ActionEvent;
import java.io.IOException;
import java.net.InetAddress;
import java.util.List;

/**
 * Trida zajistuje sitovou komunikaci pro hru dama. Reprezentuje inicializacni
 * cast peer-to-peer komunikace.
 * 
 * @author Radek Necas, xnecas18
 */
public class Initiator extends Networker {

    protected int stateInt;

    /**
     * Konstruktor vytvori novy Initiator.
     * 
     * @param controller
     *            kontroler damy
     */
    public Initiator(CheckersController controller) {
        super(controller);
    }

    /**
     * Inicializacni funkce. Vytvori klient a server, a zasle zpravu s
     * pozadavkem o spojeni ve kterem preda svoje cislo portu serveru.
     * 
     * @param remoteIp
     *            ip adresa vzdaleneho pocitace
     * @param remotePort
     *            port vzdaleneho pocitace
     * @param localPort
     *            mistni port na kterem bude naslouchat server
     * @throws IOException
     */
    public void init(InetAddress remoteIp, int remotePort, int localPort) throws IOException {
        this.client = new Client(remoteIp, remotePort);
        this.server = new Server(localPort, this);
        this.server.start();
        // Zasleme pozadavek na spojeni a cislo naseho serveru
        String port = String.valueOf(this.server.getServerSocket().getLocalPort());
        this.client.send(new Message(MessageType.ASKFORCONN, port));
    }

    // //////////////////////////////////////////////////////////////////////////
    // ////////////////// ZASILANI ZPRAV
    // ////////////////////////////////////////
    // //////////////////////////////////////////////////////////////////////////
    // region SEND MESSAGE

    /**
     * Metoda zasel informace o desce, tzn. vsechny figurky.
     * 
     * @param d
     *            deska s figurkami (z modelu)
     * @throws IOException
     */
    public void sendDeskInfo(Desk d) throws IOException {
        List<Figure> figures = d.getAllFigures();

        this.xml.initOutput(NotationReaderFactory.NotationType.IJA_NOTATION);
        for (Figure f : figures) {
            this.xml.addFigureElement(f);
        }

        System.out.println("Initiator zasila info o desce");
        this.client.send(new Message(MessageType.DESKINFO, this.xml.outputAsXml()));
        this.xml.clearOutput();
    }

    /**
     * Metoda zasle pokyn k zacatku hry
     * 
     * @throws IOException
     */
    public void sendStartGame() throws IOException {
        if (this.client == null) {
            throw new IOException("Client not created");
        }

        this.client.send(new Message(MessageType.STARTGAME, null));
    }

    // endregion SEND MESSAGE

    // //////////////////////////////////////////////////////////////////////////
    // //////////////// ZPRACOVANI UDALOSTI OD SERVERU
    // //////////////////////////
    // //////////////////////////////////////////////////////////////////////////
    // region SERVE MESSAGE

    /**
     * Metoda zpracovava udalosti od serveru, ktere jsou specificke pouze pro
     * Initiator. Ostatni preposila nadtrite Networker.
     * 
     * @param msg
     *            prijata zprava
     */
    @Override
    public void serveMessage(Message msg) {
        switch (msg.getType()) {
        case CONFIRM:
            this.fireConfirm(msg);
            break;
        default:
            super.serveMessage(msg);
        }
    }

    public void fireConfirm(Message msg) {
        Confirm conf = this.controller.createConfirmListener();
        conf.actionPerformed(new ActionEvent(this, 0, msg.getDetails()));
    }

    // endregion SERVE MESSAGE
}
